#include "ws2811.h"
#include "string.h"

uint16_t RGB_Data[WS2811S * WS2811_DATA_FRAME_LEN + WS2811_RESET_FRAME_LEN] = {0}; // 整条灯带的数据帧

/*
 *      BRG 转 RGB
 */
static uint32_t RGB_to_BRG(uint32_t RGB)
{
    return ((RGB & 0xff0000) >> 8) | ((RGB & 0x00ff00) >> 8) | ((RGB & 0x0000ff) << 16);
}

/*
 *      单独控制一个灯 (可扩展为流水灯)
 */
void ws2811_Rgb_Singleset(uint32_t RGB, uint32_t LEDn)
{
    uint8_t i, j;
    uint32_t BRG = RGB_to_BRG(RGB);

    memset(RGB_Data, 0, WS2811S * WS2811_DATA_FRAME_LEN + WS2811_RESET_FRAME_LEN);

    for (j = 0; j < LEDn; j++)
    {
        for (i = 0; i < WS2811_DATA_FRAME_LEN; i++)
        {
            RGB_Data[j * WS2811_DATA_FRAME_LEN + i] = LOW_PULSE;
        }
    }
    for (i = 0; i < WS2811_DATA_FRAME_LEN; i++)
    {
        if (BRG & 0x800000)
        {
            RGB_Data[LEDn * WS2811_DATA_FRAME_LEN + i] = HIGH_PULSE;
        }
        else
        {
            RGB_Data[LEDn * WS2811_DATA_FRAME_LEN + i] = LOW_PULSE;
        }
        BRG <<= 1;
    }

    for (j = LEDn + 1; j < WS2811S; j++)
    {
        for (i = 0; i < WS2811_DATA_FRAME_LEN; i++)
        {
            RGB_Data[j * WS2811_DATA_FRAME_LEN + i] = LOW_PULSE;
        }
    }
    HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_1, (uint32_t *)RGB_Data, WS2811S * WS2811_DATA_FRAME_LEN + WS2811_RESET_FRAME_LEN);
}

/*
 *      喷泉形式
 */
void ws2811_Fountain(uint32_t LEDn)
{
    uint8_t i, j;
    uint32_t BRG;

    memset(RGB_Data, 0, WS2811S * WS2811_DATA_FRAME_LEN + WS2811_RESET_FRAME_LEN);

    for (j = 0; j < LEDn; j++)
    {
        BRG = RGB_to_BRG(RGB_Fountain_Data[j]);
        for (i = 0; i < WS2811_DATA_FRAME_LEN; i++)
        {
            if (BRG & 0x800000)
            {
                RGB_Data[j* WS2811_DATA_FRAME_LEN + i] = HIGH_PULSE;
            }
            else
            {
                RGB_Data[j * WS2811_DATA_FRAME_LEN + i] = LOW_PULSE;
            }
            BRG <<= 1;
        }
    }

     for (j = LEDn ; j < WS2811S; j++)
    {
        for (i = 0; i < WS2811_DATA_FRAME_LEN; i++)
        {
            RGB_Data[j * WS2811_DATA_FRAME_LEN + i] = LOW_PULSE;
        }
    }

    HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_1, (uint32_t *)RGB_Data, WS2811S * WS2811_DATA_FRAME_LEN + WS2811_RESET_FRAME_LEN);
}
/*
 *      每传完一帧数据关闭DMA
 */
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
    HAL_TIM_PWM_Stop_DMA(&htim1, TIM_CHANNEL_1);
}

void ws2811_Test()
{
    static int i = 0;
    int j = 0;
    for (j = 0; j < WS2811_DATA_FRAME_LEN + WS2811_RESET_FRAME_LEN; j++)
    {
        RGB_Test[j] = RGB_Testdata[i][j];
    }
    i++;
    if (i == 3)
        i = 0;
    HAL_Delay(100);
}
